// Copyright (C) ZHENG Zhong <heavyzheng nospam-at gmail D0T com>
//
// $Id: function.hpp 227 2008-09-15 13:33:40Z heavyzheng $
//

#ifndef ZZHENG_QUANT_DATES_FUNCTION_HPP_20080602__
#define ZZHENG_QUANT_DATES_FUNCTION_HPP_20080602__

#include <zzheng/quant/dates/config.hpp>
#include <zzheng/quant/dates/date.hpp>
#include <zzheng/quant/dates/rolling.hpp>
#include <zzheng/quant/dates/duration.hpp>
#include <zzheng/quant/dates/calendar.hpp>

#include <string>

namespace zzheng {
namespace quant {
namespace dates {

    //! Parses a string to a date object.
    //! \param str  the string to parse.
    //! \return the date object.
    //! \throws date_error  if fail to parse the string to date.
    date parse_date(const std::string& str);

    //! Returns today's date.
    //! \return today's date.
    date today();

    //! Creates a date using Excel day. Dates before 1900-01-01 are considered as empty.
    //! \param excel_day  the MS Excel day.
    //! \return the constructed date.
    date create_from_excel_day(int excel_day);

    //! Returns the day count from 1900-01-01. Note that this function returns the same result as
    //! MS Excel if the date is after 1900-03-01. For dates before 1900-03-01, the value returned
    //! by this function is greater than the value calculated by MS Excel by 1. This is because the
    //! date 1900-02-29 is not counted by this function.
    //! \param d  the date to count the excel days for.
    //! \return the day count from 1900-01-01.
    int get_excel_day(const date& d);

    //! Adjusts the date under the given holiday calendar, using the given rolling convention.
    //! \param d        the date to adjust.
    //! \param rolling  the rolling convention.
    //! \param cal      the holiday calendar.
    //! \return the adjusted date.
    date adjust(const date& d, rolling_t rolling, const calendar& cal);

    //! Parses a string to a duration object.
    //! \param str  the string to parse.
    //! \return the duration object.
    //! \throws date_error  if fail to parse the string to duration.
    duration parse_duration(const std::string& str);

    //! Makes a duration object from number of days.
    //! \param count  the number of days.
    //! \return the duration object.
    duration make_days(duration::count_type count);

    //! Makes a duration object from number of weeks.
    //! \param count  the number of weeks.
    //! \return the duration object.
    duration make_weeks(duration::count_type count);

    //! Makes a duration object from number of months.
    //! \param count  the number of months.
    //! \return the duration object.
    duration make_months(duration::count_type count);

    //! Makes a duration object from number of years.
    //! \param count  the number of years.
    //! \return the duration object.
    duration make_years(duration::count_type count);

    //! Adds a duration to a date.
    //! \param d             the date to add.
    //! \param delta         the duration to add.
    //! \param end_of_month  whether to use the end-of-month convention.
    //! \return the new date.
    date add_duration(const date& d, const duration& delta, bool end_of_month);

    //! Returns a dummy holiday calendar in which Saturday and Sunday are weekends and no holidays.
    //! \return the dummy holiday calendar.
    calendar get_dummy_calendar();

} // namespace zzheng::quant::dates
} // namespace zzheng::quant
} // namespace zzheng


#endif // ZZHENG_QUANT_DATES_FUNCTION_HPP_20080602__



